package fag.core.geometry;

import java.awt.geom.AffineTransform;
import java.io.Serializable;

import fag.core.collision.Hitbox;

/**
 * Classe des cercles 2D. Le cercle est défini par son centre, et son rayon.
 * @author lumz
 */
public class Circle2D extends Hitbox implements Cloneable, Serializable {

	private static final long serialVersionUID = 2570122839929291178L;
	
	private Vector2D center = new Vector2D(0, 0);
	private double radius = 0;
	
	/**
	 * Constructeur par défault.
	 * Initialise les coordonnées à 0, 0 avec un rayon nul.
	 */
	public Circle2D() {
	}
	
	/**
	 * Constructeur de Circle.
	 * @param center Le centre du cercle.
	 * @param radius Le rayon du cercle.
	 */
	public Circle2D(Vector2D center, double radius) {
		this.center = center.clone();
		this.radius = radius;
	}
	
	/**
	 * Constructeur de Circle.
	 * @param x Coordonnée x du centre du cercle.
	 * @param y Coordonnée y du centre du cercle.
	 * @param radius Le rayon du cercle.
	 */
	public Circle2D(double x, double y, double radius) {
		center.set(x, y);
		this.radius = radius;
	}
	
	@Override
	public Circle2D clone() {
		return (Circle2D) super.clone();
	}

	@Override
	public Rectangle2D getBounds() {
		return new Rectangle2D(center.x - radius, center.y - radius, radius * 2, radius * 2);
	}
	
	/**
	 * Getter des coordonnées du centre du cercle.
	 * @return La coordonnées du centre du cercle.
	 */
	public Vector2D getCenter() {
		return center.clone();
	}
	
	/**
	 * Getter du rayon.
	 * @return La valeur du rayon.
	 */
	public double getRadius() {
		return radius;
	}
	
	/**
	 * Getter de la coordonnée x du centre du cercle.
	 * @return La coordonnée x du centre du cercle.
	 */
	public double getX() {
		return center.x;
	}
	
	/**
	 * Getter de la coordonnée y du centre du cercle.
	 * @return La coordonnée y du centre du cercle.
	 */
	public double getY() {
		return center.y;
	}

	/**
	 * Setter du cercle.
	 * @param center Coordonnées du centre du cercle.
	 * @param radius Rayon du cercle.
	 */
	public void set(Vector2D center, double radius) {
		this.center = center.clone();
		this.radius = radius;
	}
	
	/**
	 * Setter du cercle.
	 * @param x Coordonnée x du centre du cercle.
	 * @param y Coordonnée y du centre du cercle.
	 * @param radius Rayon du cercle.
	 */
	public void set(double x, double y, double radius) {
		center.set(x, y);
		this.radius = radius;
	}
	
	/**
	 * Setter des coordonnées du centre du cercle.
	 * @param center Coordonnées du centre du cercle.
	 */
	public void setCenter(Vector2D center) {
		this.center = center.clone();
	}
	
	/**
	 * Setter des coordonnées du centre du cercle.
	 * @param x Coordonnée x du centre du cercle.
	 * @param y Coordonnéé y du centre du cercle.
	 */
	public void setCenter(double x, double y) {
		center.set(x, y);
	}
	
	/**
	 * Setter du rayon.
	 * @param radius La nouvelle valeur du rayon.
	 */
	public void setRadius(double radius) {
		this.radius = radius; 
	}
	
	/**
	 * Implémentation pour Collidable.
	 * @param Vecteur d utilisé dans Gjk.
	 * @return Le sommet utilisé pour la construction du simplex.
	 */
	public Vector2D supportMapping(Vector2D d) {
		
		double length = d.length();
		if(length > 0)
			return d.mul(radius / length).add(center);
		else
			return new Vector2D();
	}
	
	@Override
	public String toString() {
		return new String() + "Circle2D(" + center.x + ", " + center.y + ", " + radius + ")";
	}
	
	@Override
	public Circle2D transform(AffineTransform transformation) {
		return new Circle2D(center.transform(transformation), radius);
	}
}
